<?php

namespace App\Http\Controllers\Api\v1;

use App\Models\Article;
use App\Transformers\ArticleTransformer;
use Illuminate\Http\Request;

class ArticleController extends BaseController
{
    /**
     * Instanceof article
     *
     * @var Article
     */
    private $model;

    /**
     * Instanceof articleTransformer
     *
     * @var ArticleTransformer
     */
    private $transformer;


    /**
     * articleController constructor.
     * @param Article $model
     * @param ArticleTransformer $transformer
     */
    public function __construct(Article $model, ArticleTransformer $transformer)
    {
        $this->model = $model;
        $this->transformer = $transformer;
        $this->middleware('jwt.auth', ['except' => ['index', 'show']]);
        $this->middleware('jwt.refresh', ['except' => ['index', 'show']]);
    }

    /**
     * @param Request $request
     * @return \Dingo\Api\Http\Response
     */
    public function index(Request $request)
    {
        $articles = $this->model->filter($request->all())->paginate();
        return $this->response->paginator($articles, $this->transformer);
    }

    /**
     * @param $id
     * @return \Dingo\Api\Http\Response|mixed
     */
    public function show($id)
    {
        $article = $this->model->query()->find($id);
        if (!$article) {
            return $this->response->errorNotFound();
        }
        return $this->response->item($article, $this->transformer);
    }

    /**
     * @param Request $request
     * @return \Dingo\Api\Http\Response|mixed
     * @throws \Throwable
     */
    public function store(Request $request)
    {
        $this->validateField($request, $this->createRules());
        $article = $this->model->query()->create($request->all());
        // todo:关联模型插入
        if (!$article) {
            return $this->response->errorInternal('Error occurred on creating article');
        }
        return $this->response->item($article, $this->transformer);
    }

    /**
     * @param Request $request
     * @param $id
     * @return \Dingo\Api\Http\Response|mixed
     * @throws \Throwable
     */
    public function update(Request $request, $id)
    {
        $article = $this->model->query()->find($id);
        if (!$article) {
            return $this->response->errorNotFound();
        }
        $this->validateField($request, $this->updateRules($article));
        $saved = $article->update($request->only($this->fields()));
        if (!$saved) {
            return $this->response->errorInternal('Error occurred on updating article');
        }
        return $this->response->item($article, $this->transformer);
    }

    /**
     * @param $id
     * @return \Dingo\Api\Http\Response|mixed
     * @throws \Exception
     */
    public function destroy($id)
    {
        $article = $this->model->query()->find($id);
        if (!$article) {
            return $this->response->errorNotFound();
        }
        $deleted = $article->delete();
        if (!$deleted) {
            return $this->response->errorInternal('Error occurred on updating article');
        }
        return $this->response->noContent();
    }

    /**
     * @return array
     */
    public function createRules(): array
    {
        return [
            'user_id' => 'required',
            'node_id' => 'required',
            'title' => 'required|unique:articles,title',
        ];
    }

    /**
     * @param Article $model
     * @return array
     */
    public function updateRules($model): array
    {
        return [
            'user_id' => 'required',
            'node_id' => 'required',
            'title' => 'required|unique:articles,title,' . $model->id,
        ];
    }

    public function fields()
    {
        return [
            'user_id', 'title', 'node_id',
            'pinned_at', 'frozen_at', 'published_at',
            'views_count', 'likes_count', 'comments_count',
            'status', 'allow_comment', 'pinned',
            'keywords', 'description',
        ];
    }

}